package com.chenyuxin.ilp.security.perm.jwt;

import com.chenyuxin.ilp.security.perm.handler.PermException;
import com.chenyuxin.ilp.model.enums.exception.UserExceptionEnums;
import com.chenyuxin.ilp.model.vo.user.UserLoginVo;
import com.chenyuxin.ilp.util.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
@Slf4j
public class UserJWTAuthenticationFilter extends OncePerRequestFilter {
//    private final String jwtKey = "12345678";
//    @Override
//    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
//                                    FilterChain filterChain) throws ServletException, IOException {
//        log.info("Use UserJWTAuthenticationFilter");
//        String jwtToken = request.getHeader("Authorization");
//        if(StrUtil.isEmpty(jwtToken)){
//            throw new PermException(UserExceptionEnums.NOT_LOGIN);
//        }
//        if (jwtToken.startsWith("Bearer ")) {
//            jwtToken = jwtToken.substring(7);
//        }
//        boolean verify;
//        try{
//            verify = JWTUtil.verify(jwtToken, jwtKey.getBytes(StandardCharsets.UTF_8));
//        }catch (Exception e){
//            throw new PermException(UserExceptionEnums.TOKEN_ERROR);
//        }
//        if(!verify){
//            throw new PermException(UserExceptionEnums.JWT_KEY_ERROR);
//        }
//        JSONObject payloads = JWTUtil.parseToken(jwtToken).getPayloads();
//        long expireTime = ((Number)payloads.get("exp")).longValue();
//        if(System.currentTimeMillis()>expireTime){
//            throw new PermException(UserExceptionEnums.TOKEN_EXPIRE);
//        }
//        UserLoginVo userLoginVo = JSONUtil.toBean(payloads, UserLoginVo.class);
//        UserJwtAuthentication authentication = new UserJwtAuthentication();
//        authentication.setJwtToken(jwtToken);
//        authentication.setAuthenticated(true); // 设置true，认证通过。
//        authentication.setCurrentUser(userLoginVo);
//        // 认证通过后，一定要设置到SecurityContextHolder里面去。
//        SecurityContextHolder.getContext().setAuthentication(authentication);
//        // 放行
//        filterChain.doFilter(request, response);
//    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
                                    FilterChain filterChain) throws ServletException, IOException {
        log.info("Use UserJWTAuthenticationFilter");

        // 获取Token逻辑保持不变...
        String jwtToken = request.getHeader("Authorization");
        if (jwtToken.startsWith("Bearer ")) {
            jwtToken = jwtToken.substring(7);
        }
        try {
            // JJWT验证解析一步完成
            Claims claims = JwtUtils.parseToken(jwtToken);

            // 自动验证过期时间（无需手动检查）
            UserLoginVo userLoginVo = extractUserFromClaims(claims);

            // 设置认证信息...
            UserJwtAuthentication authentication = new UserJwtAuthentication();
            authentication.setJwtToken(jwtToken);
            authentication.setAuthenticated(true);
            authentication.setCurrentUser(userLoginVo);
            SecurityContextHolder.getContext().setAuthentication(authentication);

        } catch (JwtException | IllegalArgumentException e) {
           log.error(e.getMessage());
           this.handleJwtException(e);
        }

        filterChain.doFilter(request, response);
    }

    private UserLoginVo extractUserFromClaims(Claims claims) {
        return UserLoginVo.builder()
                .id(claims.get("id", String.class))
                .username(claims.get("username", String.class))
                .img(claims.get("img", String.class))
                .phone(claims.get("phone", String.class))
                .build();
    }

    private void handleJwtException(Exception ex) {
        if (ex instanceof io.jsonwebtoken.ExpiredJwtException) {
            throw new PermException(UserExceptionEnums.TOKEN_EXPIRE);
        } else if (ex instanceof io.jsonwebtoken.security.SignatureException) {
            throw new PermException(UserExceptionEnums.JWT_KEY_ERROR);
        } else {
            throw new PermException(UserExceptionEnums.TOKEN_ERROR);
        }
    }
}

